﻿namespace Cellfish.Test.Fakes.System
{
    using global::System;

    using Microsoft.VisualStudio.TestTools.UnitTesting;

    /// <summary>
    /// Implements fake observer.
    /// </summary>
    /// <typeparam name="T">Type to observe.</typeparam>
    public class FakeObserver<T> : IObserver<T>
    {
        /// <summary>
        /// Gets or sets the behavior for OnNext.
        /// </summary>
        /// <value>
        /// The OnNext behavior.
        /// </value>
        public Action<T> OnNext { private get; set; }

        /// <summary>
        /// Gets or sets the behavior for OnError.
        /// </summary>
        /// <value>
        /// The OnError behavior.
        /// </value>
        public Action<Exception> OnError { private get; set; }

        /// <summary>
        /// Gets or sets the behavior for OnCompleted.
        /// </summary>
        /// <value>
        /// The OnCompleted behavior.
        /// </value>
        public Action OnCompleted { get; set; }

        /// <summary>
        /// Provides the observer with new data.
        /// </summary>
        /// <param name="value">The current notification information.</param>
        void IObserver<T>.OnNext(T value)
        {
            Assert.IsNotNull(this.OnNext, "Unexpected call to OnNext({0}).", value);
            this.OnNext(value);
        }

        /// <summary>
        /// Notifies the observer that the provider has experienced an error condition.
        /// </summary>
        /// <param name="error">An object that provides additional information about the error.</param>
        void IObserver<T>.OnError(Exception error)
        {
            Assert.IsNotNull(this.OnNext, "Unexpected call to OnError({0}).", error);
            this.OnError(error);
        }

        /// <summary>
        /// Notifies the observer that the provider has finished sending push-based notifications.
        /// </summary>
        void IObserver<T>.OnCompleted()
        {
            Assert.IsNotNull(this.OnNext, "Unexpected call to OnCompleted().");
            this.OnCompleted();
        }
    }
}
